<template>
  <view class="rich-text-editor" :class="themeClass">
    <!-- 工具栏 -->
    <view class="editor-toolbar">
      <view class="toolbar-group">
        <view 
          class="toolbar-btn" 
          :class="{ active: formats.bold }"
          @click="format('bold')"
        >
          <text class="btn-text bold">B</text>
        </view>
        <view 
          class="toolbar-btn" 
          :class="{ active: formats.italic }"
          @click="format('italic')"
        >
          <text class="btn-text italic">I</text>
        </view>
        <view 
          class="toolbar-btn" 
          :class="{ active: formats.underline }"
          @click="format('underline')"
        >
          <text class="btn-text underline">U</text>
        </view>
      </view>
      
      <view class="toolbar-group">
        <view class="toolbar-btn" @click="format('header', 1)">
          <text class="btn-text">H1</text>
        </view>
        <view class="toolbar-btn" @click="format('header', 2)">
          <text class="btn-text">H2</text>
        </view>
      </view>
      
      <view class="toolbar-group">
        <view class="toolbar-btn" @click="insertImage">
          <text class="btn-text">📷</text>
        </view>
        <view class="toolbar-btn" @click="insertDivider">
          <text class="btn-text">—</text>
        </view>
      </view>
    </view>
    
    <!-- 编辑区域 -->
    <view class="editor-content">
      <!-- H5平台的块状编辑器 -->
      <!-- #ifdef H5 -->
      <view class="blocks-container">
        <view 
          v-for="(block, index) in blocks" 
          :key="block.id"
          class="content-block"
          :class="{ active: activeBlockIndex === index }"
          @click="focusBlock(index)"
        >
          <!-- 文本块 -->
          <view v-if="block.type === 'text'" class="text-block">
            <view 
              class="text-input"
              :class="block.format"
              contenteditable="true"
              :data-placeholder="block.content ? '' : (index === 0 ? placeholder : '输入文本...')"
              @input="onTextInput(index, $event)"
              @focus="onTextFocus(index)"
              @blur="onTextBlur(index)"
              @keydown="onKeyDown(index, $event)"
              v-html="block.content"
            ></view>
            
            <!-- 删除按钮 -->
            <view 
              v-if="blocks.length > 1"
              class="block-delete" 
              @click="deleteBlock(index)"
            >
              <text class="delete-icon">×</text>
            </view>
          </view>
          
          <!-- 图片块 -->
          <view v-else-if="block.type === 'image'" class="image-block">
            <view class="image-wrapper">
              <image 
                :src="block.src" 
                mode="widthFix"
                class="block-image"
                @load="onImageLoad"
                @error="onImageError"
              />
              <view class="image-actions">
                <view class="action-btn" @click="deleteBlock(index)">
                  <text class="action-icon">🗑️</text>
                </view>
              </view>
            </view>
          </view>
          
          <!-- 分割线块 -->
          <view v-else-if="block.type === 'divider'" class="divider-block">
            <view class="divider-line"></view>
            <view class="block-delete" @click="deleteBlock(index)">
              <text class="delete-icon">×</text>
            </view>
          </view>
        </view>
        
        <!-- 添加按钮 -->
        <view class="add-block-section">
          <view class="add-btn" @click="addTextBlock">
            <text class="add-icon">+</text>
            <text class="add-text">添加段落</text>
          </view>
        </view>
      </view>
      <!-- #endif -->
      
      <!-- 非H5平台使用原有的editor组件 -->
      <!-- #ifndef H5 -->
      <editor
        id="editor"
        class="native-editor"
        :placeholder="placeholder"
        :show-img-size="false"
        :show-img-toolbar="false"
        @ready="onEditorReady"
        @focus="onEditorFocus"
        @blur="onEditorBlur"
        @input="onEditorInput"
        @statuschange="onStatusChange"
      ></editor>
      <!-- #endif -->
    </view>
  </view>
</template>

<script>
import { uploadImageAPI } from '@/api/upload'
import { extractResponseData } from '@/utils/index'

export default {
  name: 'RichTextEditor',
  props: {
    placeholder: {
      type: String,
      default: '开始写作...'
    },
    value: {
      type: String,
      default: ''
    },
    themeMode: {
      type: String,
      default: 'light'
    }
  },
  emits: ['update:value', 'input', 'focus', 'blur'],
  data() {
    return {
      // H5平台的块状编辑器
      blocks: [
        {
          id: this.generateId(),
          type: 'text',
          content: '',
          format: 'normal'
        }
      ],
      activeBlockIndex: 0,
      
      // 格式化状态
      formats: {
        bold: false,
        italic: false,
        underline: false
      },
      
      // 原生编辑器相关
      editorCtx: null,
      editorReady: false,
      
      // 输入处理
      emitTimeout: null,
      isUpdatingContent: false
    }
  },
  computed: {
    themeClass() {
      return this.themeMode === 'dark' ? 'theme-dark' : 'theme-light'
    }
  },
  watch: {
    value: {
      handler(newValue) {
        if (!this.isUpdatingContent) {
          this.setContent(newValue)
        }
      },
      immediate: true
    }
  },
  beforeDestroy() {
    if (this.emitTimeout) {
      clearTimeout(this.emitTimeout)
    }
  },
  methods: {
    generateId() {
      return Date.now().toString(36) + Math.random().toString(36).substr(2)
    },
    
    // 设置内容
    setContent(html) {
      // #ifdef H5
      if (!html) {
        this.blocks = [{
          id: this.generateId(),
          type: 'text',
          content: '',
          format: 'normal'
        }]
        return
      }
      
      // 解析HTML内容为块
      this.parseHtmlToBlocks(html)
      // #endif
      
      // #ifndef H5
      if (this.editorCtx && html) {
        this.editorCtx.setContents({
          html: html
        })
      }
      // #endif
    },
    
    // 解析HTML为块结构
    parseHtmlToBlocks(html) {
      // #ifdef H5
      // H5平台的HTML解析
      const blocks = []
      
      // 使用简单的正则表达式来解析
      const imgRegex = /<img[^>]+src="([^"]*)"[^>]*>/g
      const parts = html.split(imgRegex)
      
      for (let i = 0; i < parts.length; i += 2) {
        // 文本部分
        const textContent = parts[i]
        if (textContent && textContent.trim()) {
          blocks.push({
            id: this.generateId(),
            type: 'text',
            content: textContent.replace(/<[^>]*>/g, '').trim(),
            format: 'normal'
          })
        }
        
        // 图片部分
        if (parts[i + 1]) {
          blocks.push({
            id: this.generateId(),
            type: 'image',
            src: parts[i + 1],
            alt: '图片'
          })
        }
      }
      
      if (blocks.length === 0) {
        blocks.push({
          id: this.generateId(),
          type: 'text',
          content: '',
          format: 'normal'
        })
      }
      
      this.blocks = blocks
      // #endif
      
      // #ifndef H5
      // 非H5平台暂时不解析HTML，直接设置为文本内容
      this.blocks = [{
        id: this.generateId(),
        type: 'text',
        content: html || '',
        format: 'normal'
      }]
      // #endif
    },
    
    // 输出内容
    emitContent() {
      // #ifdef H5
      this.isUpdatingContent = true
      const html = this.blocksToHtml()
      this.$emit('update:value', html)
      this.$emit('input', html)
      this.$nextTick(() => {
        this.isUpdatingContent = false
      })
      // #endif
    },
    
    // 将块转换为HTML
    blocksToHtml() {
      return this.blocks.map(block => {
        if (block.type === 'text') {
          const content = block.content || ''
          switch (block.format) {
            case 'header1': return `<h1>${content}</h1>`
            case 'header2': return `<h2>${content}</h2>`
            case 'bold': return `<strong>${content}</strong>`
            case 'italic': return `<em>${content}</em>`
            case 'underline': return `<u>${content}</u>`
            default: return `<p>${content}</p>`
          }
        } else if (block.type === 'image') {
          return `<img src="${block.src}" alt="${block.alt || '图片'}" style="max-width: 100%; height: auto;" />`
        } else if (block.type === 'divider') {
          return '<hr />'
        }
        return ''
      }).join('')
    },
    
    // 文本输入
    onTextInput(index, event) {
      const content = event.target.innerText || event.target.textContent
      // 直接更新blocks数组，避免触发watch
      this.$set(this.blocks, index, {
        ...this.blocks[index],
        content: content
      })
      
      // 手动触发内容更新
      this.emitContentDelayed()
    },
    
    // 延迟触发内容更新，避免频繁调用
    emitContentDelayed() {
      if (this.emitTimeout) {
        clearTimeout(this.emitTimeout)
      }
      this.emitTimeout = setTimeout(() => {
        this.emitContent()
      }, 300)
    },
    
    // 文本焦点
    onTextFocus(index) {
      this.activeBlockIndex = index
      this.$emit('focus')
    },
    
    onTextBlur(index) {
      this.$emit('blur')
    },
    
    // 键盘事件
    onKeyDown(index, event) {
      // Enter键创建新的文本块
      if (event.key === 'Enter' && !event.shiftKey) {
        event.preventDefault()
        this.addTextBlock(index + 1)
      }
      
      // Backspace删除空的文本块
      if (event.key === 'Backspace' && this.blocks[index].content === '' && this.blocks.length > 1) {
        event.preventDefault()
        this.deleteBlock(index)
        // 焦点移到上一个块
        if (index > 0) {
          this.focusBlock(index - 1)
        }
      }
    },
    
    // 聚焦块
    focusBlock(index) {
      this.activeBlockIndex = index
      // #ifdef H5
      this.$nextTick(() => {
        const textInputs = document.querySelectorAll('.text-input')
        if (textInputs[index]) {
          textInputs[index].focus()
        }
      })
      // #endif
    },
    
    // 添加文本块
    addTextBlock(index = null) {
      // 先保存当前正在编辑的内容
      this.saveCurrentBlockContent()
      
      const newIndex = index !== null ? index : this.blocks.length
      const newBlock = {
        id: this.generateId(),
        type: 'text',
        content: '',
        format: 'normal'
      }
      
      this.blocks.splice(newIndex, 0, newBlock)
      this.emitContent()
      
      this.$nextTick(() => {
        this.focusBlock(newIndex)
      })
    },
    
    // 删除块
    deleteBlock(index) {
      if (this.blocks.length > 1) {
        this.blocks.splice(index, 1)
        this.emitContent()
        
        // 调整活动块索引
        if (this.activeBlockIndex >= index && this.activeBlockIndex > 0) {
          this.activeBlockIndex--
        }
        
        // 重新聚焦
        this.$nextTick(() => {
          this.focusBlock(this.activeBlockIndex)
        })
      }
    },
    
    // 格式化
    format(type, value) {
      // #ifdef H5
      // 先保存当前正在编辑的内容
      this.saveCurrentBlockContent()
      
      if (type === 'header') {
        this.$set(this.blocks, this.activeBlockIndex, {
          ...this.blocks[this.activeBlockIndex],
          format: `header${value}`
        })
      } else if (['bold', 'italic', 'underline'].includes(type)) {
        const currentFormat = this.blocks[this.activeBlockIndex].format
        const newFormat = currentFormat === type ? 'normal' : type
        this.$set(this.blocks, this.activeBlockIndex, {
          ...this.blocks[this.activeBlockIndex],
          format: newFormat
        })
      }
      
      // 延迟更新内容和重新聚焦
      this.$nextTick(() => {
        this.emitContent()
        this.refocusCurrentBlock()
      })
      // #endif
      
      // #ifndef H5
      if (this.editorCtx) {
        this.editorCtx.format(type, value)
      }
      // #endif
    },
    
    // 保存当前块的内容
    saveCurrentBlockContent() {
      // #ifdef H5
      const textInputs = document.querySelectorAll('.text-input')
      const currentInput = textInputs[this.activeBlockIndex]
      if (currentInput && this.blocks[this.activeBlockIndex].type === 'text') {
        const content = currentInput.innerText || currentInput.textContent || ''
        this.blocks[this.activeBlockIndex].content = content
      }
      // #endif
    },
    
    // 重新聚焦当前块
    refocusCurrentBlock() {
      // #ifdef H5
      this.$nextTick(() => {
        const textInputs = document.querySelectorAll('.text-input')
        const currentInput = textInputs[this.activeBlockIndex]
        if (currentInput) {
          currentInput.focus()
          // 将光标移到最后
          const range = document.createRange()
          const sel = window.getSelection()
          range.selectNodeContents(currentInput)
          range.collapse(false)
          sel.removeAllRanges()
          sel.addRange(range)
        }
      })
      // #endif
    },
    
    // 插入分割线
    insertDivider() {
      // #ifdef H5
      // 先保存当前正在编辑的内容
      this.saveCurrentBlockContent()
      
      const dividerBlock = {
        id: this.generateId(),
        type: 'divider'
      }
      
      this.blocks.splice(this.activeBlockIndex + 1, 0, dividerBlock)
      
      // 在分割线后添加一个新的文本块
      const textBlock = {
        id: this.generateId(),
        type: 'text',
        content: '',
        format: 'normal'
      }
      this.blocks.splice(this.activeBlockIndex + 2, 0, textBlock)
      
      this.activeBlockIndex = this.activeBlockIndex + 2
      this.emitContent()
      
      this.$nextTick(() => {
        this.focusBlock(this.activeBlockIndex)
      })
      // #endif
    },
    
    // 插入图片
    async insertImage() {
      try {
        const res = await uni.chooseImage({
          count: 1,
          sizeType: ['compressed'],
          sourceType: ['album', 'camera']
        })
        
        if (res.tempFilePaths && res.tempFilePaths.length > 0) {
          const tempPath = res.tempFilePaths[0]
          
          // 检查文件大小（限制为5MB）
          try {
            const fileInfo = await uni.getFileInfo({
              filePath: tempPath
            })
            
            if (fileInfo.size > 5 * 1024 * 1024) {
              uni.showToast({
                title: '图片大小不能超过5MB',
                icon: 'none'
              })
              return
            }
          } catch (e) {
            console.warn('无法获取文件信息:', e)
          }
          
          uni.showLoading({
            title: '上传中...'
          })
          
          try {
            // 上传图片
            const uploadRes = await uploadImageAPI(tempPath)
            console.log('上传响应:', uploadRes)
            
            const uploadData = extractResponseData(uploadRes)
            console.log('提取的数据:', uploadData)
            
            // 检查上传结果
            if (!uploadData || !uploadData.url) {
              throw new Error('服务器未返回图片URL')
            }
            
            // 处理图片URL - 如果是相对路径，转换为完整URL
            let imageUrl = uploadData.url
            if (imageUrl.startsWith('/')) {
              // 从request.js获取baseURL
              const baseURL = 'http://192.168.31.100:3000'
              imageUrl = baseURL + imageUrl
            }
            console.log('处理后的图片URL:', imageUrl)
            
            // #ifdef H5
            // 先保存当前正在编辑的内容
            this.saveCurrentBlockContent()
            
            // 在当前活动块后插入图片块
            const imageBlock = {
              id: this.generateId(),
              type: 'image',
              src: imageUrl,
              alt: '图片'
            }
            
            this.blocks.splice(this.activeBlockIndex + 1, 0, imageBlock)
            
            // 在图片后添加一个新的文本块
            const textBlock = {
              id: this.generateId(),
              type: 'text',
              content: '',
              format: 'normal'
            }
            this.blocks.splice(this.activeBlockIndex + 2, 0, textBlock)
            
            this.activeBlockIndex = this.activeBlockIndex + 2
            this.emitContent()
            
            this.$nextTick(() => {
              this.focusBlock(this.activeBlockIndex)
            })
            // #endif
            
            // #ifndef H5
            if (this.editorCtx) {
              this.editorCtx.insertImage({
                src: uploadData.url,
                alt: '图片',
                width: '100%',
                height: 'auto'
              })
            }
            // #endif
            
            uni.hideLoading()
            uni.showToast({
              title: '图片插入成功',
              icon: 'success'
            })
          } catch (error) {
            uni.hideLoading()
            console.error('图片上传失败:', error)
            
            let errorMessage = '图片上传失败'
            if (error.message) {
              errorMessage = error.message
            } else if (error.data && error.data.message) {
              errorMessage = error.data.message
            }
            
            uni.showToast({
              title: errorMessage,
              icon: 'none',
              duration: 3000
            })
          }
        }
      } catch (error) {
        console.error('选择图片失败:', error)
        uni.showToast({
          title: '选择图片失败',
          icon: 'none'
        })
      }
    },
    
    // 原生编辑器事件
    onEditorReady() {
      // #ifndef H5
      uni.createSelectorQuery().in(this).select('#editor').context((res) => {
        this.editorCtx = res.context
        this.editorReady = true
        
        if (this.value) {
          this.setContent(this.value)
        }
      }).exec()
      // #endif
    },
    
    onEditorFocus() {
      this.$emit('focus')
    },
    
    onEditorBlur() {
      this.$emit('blur')
    },
    
    onEditorInput() {
      // #ifndef H5
      if (this.editorCtx) {
        this.editorCtx.getContents({
          success: (res) => {
            this.$emit('update:value', res.html)
            this.$emit('input', res.html)
          }
        })
      }
      // #endif
    },
    
    onStatusChange(e) {
      this.formats = e.detail
    },
    
    onImageLoad() {
      // 图片加载成功
    },
    
    onImageError() {
      uni.showToast({
        title: '图片加载失败',
        icon: 'none'
      })
    },
    
    // 获取内容
    getContent() {
      // #ifdef H5
      return this.blocksToHtml()
      // #endif
      
      // #ifndef H5
      return new Promise((resolve) => {
        if (this.editorCtx) {
          this.editorCtx.getContents({
            success: (res) => {
              resolve(res.html)
            },
            fail: () => {
              resolve('')
            }
          })
        } else {
          resolve('')
        }
      })
      // #endif
    }
  }
}
</script>

<style scoped>
.rich-text-editor {
  background-color: #ffffff;
  border-radius: 16rpx;
  overflow: hidden;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
}

.editor-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20rpx;
  background-color: #f8f9fa;
  border-bottom: 1rpx solid #e9ecef;
  flex-wrap: wrap;
  gap: 20rpx;
}

.toolbar-group {
  display: flex;
  gap: 16rpx;
}

.toolbar-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 60rpx;
  height: 60rpx;
  border-radius: 30rpx;
  background-color: #ffffff;
  border: 1rpx solid #dee2e6;
  transition: all 0.2s ease;
  user-select: none;
  -webkit-user-select: none;
}

.toolbar-btn:active {
  background-color: #e9ecef;
}

.toolbar-btn.active {
  background-color: #007aff;
  border-color: #007aff;
}

.toolbar-btn.active .btn-text {
  color: #ffffff;
}

.btn-text {
  font-size: 24rpx;
  font-weight: 500;
  color: #495057;
}

.btn-text.bold {
  font-weight: bold;
}

.btn-text.italic {
  font-style: italic;
}

.btn-text.underline {
  text-decoration: underline;
}

.editor-content {
  min-height: 400rpx;
}

.blocks-container {
  padding: 20rpx;
}

.content-block {
  position: relative;
  margin-bottom: 20rpx;
  min-height: 60rpx;
}

.content-block.active {
  outline: 2rpx solid #007aff;
  outline-offset: 4rpx;
  border-radius: 8rpx;
}

.text-block {
  position: relative;
}

.text-input {
  width: 100%;
  min-height: 60rpx;
  padding: 20rpx;
  font-size: 30rpx;
  line-height: 1.6;
  color: #333333;
  border: 2rpx solid transparent;
  border-radius: 8rpx;
  outline: none;
  transition: border-color 0.2s;
  word-wrap: break-word;
  word-break: break-all;
}

.text-input:focus {
  border-color: #007aff;
}

.text-input[data-placeholder]:empty::before {
  content: attr(data-placeholder);
  color: #cccccc;
  pointer-events: none;
}

.text-input.header1 {
  font-size: 48rpx;
  font-weight: bold;
  margin: 20rpx 0;
}

.text-input.header2 {
  font-size: 40rpx;
  font-weight: bold;
  margin: 16rpx 0;
}

.text-input.bold {
  font-weight: bold;
}

.text-input.italic {
  font-style: italic;
}

.text-input.underline {
  text-decoration: underline;
}

.image-block {
  margin: 20rpx 0;
  position: relative;
}

.image-wrapper {
  position: relative;
  border-radius: 12rpx;
  overflow: hidden;
}

.block-image {
  width: 100%;
  max-height: 600rpx;
  object-fit: cover;
}

.image-actions {
  position: absolute;
  top: 16rpx;
  right: 16rpx;
  display: flex;
  gap: 12rpx;
}

.action-btn {
  width: 60rpx;
  height: 60rpx;
  border-radius: 30rpx;
  background-color: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
}

.action-icon {
  font-size: 24rpx;
}

.divider-block {
  position: relative;
  margin: 40rpx 0;
}

.divider-line {
  height: 2rpx;
  background-color: #e9ecef;
  width: 100%;
}

.block-delete {
  position: absolute;
  top: -12rpx;
  right: -12rpx;
  width: 48rpx;
  height: 48rpx;
  border-radius: 24rpx;
  background-color: #ff4d4f;
  color: #ffffff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 32rpx;
  font-weight: bold;
  z-index: 10;
}

.add-block-section {
  margin-top: 40rpx;
  text-align: center;
}

.add-btn {
  display: inline-flex;
  align-items: center;
  gap: 12rpx;
  padding: 20rpx 40rpx;
  background-color: #f8f9fa;
  border: 2rpx dashed #dee2e6;
  border-radius: 8rpx;
  color: #666666;
}

.add-icon {
  font-size: 32rpx;
  font-weight: bold;
}

.add-text {
  font-size: 28rpx;
}

.native-editor {
  width: 100%;
  min-height: 400rpx;
  padding: 20rpx;
}

/* 主题适配 */
.theme-dark.rich-text-editor {
  background-color: #252526;
}

.theme-dark .editor-toolbar {
  background-color: #2d2d30;
  border-bottom-color: #404040;
}

.theme-dark .toolbar-btn {
  background-color: #404040;
  border-color: #555555;
}

.theme-dark .btn-text {
  color: #b3b3b3;
}

.theme-dark .text-input {
  color: #e8e8e8;
  border-color: #404040;
}

.theme-dark .text-input:focus {
  border-color: #007aff;
}

.theme-dark .text-input[data-placeholder]:empty::before {
  color: #8c8c8c;
}

.theme-dark .add-btn {
  background-color: #404040;
  border-color: #555555;
  color: #b3b3b3;
}

.theme-dark .divider-line {
  background-color: #404040;
}
</style> 